var Utils = require('geoUtils');
//
cc.Class({
    extends: cc.Component,

    properties: {
        cameraNodeName: {
            default: 'Main Camera',
            tooltip: '不指定camera的情况下，通过名字查找camera',
        },
        camera: {
            default: null,
            type: cc.Node,
            tooltip: '被控制的摄像机节点'
        },
        cameraSize: {
            default: null,
            type: cc.Node,
            tooltip: '摄像机尺寸(留空即为屏幕尺寸)'
        },
        cameraBounds: {
            default: null,
            type: cc.Node,
            tooltip: '摄像机边界(控制器会尽力保证摄像机尺寸不跃出摄像机边界，留空即为无边界)'
        },
        target: {
            default: null,
            type: cc.Node,
            tooltip: '目标节点'
        },
        targetSize: {
            default: null,
            type: cc.Node,
            tooltip: '目标尺寸(留空即为target节点自身尺寸)'
        },
        targetBounds: {
            default: null,
            type: cc.Node,
            tooltip: '目标区域(控制器会尽力保证目标尺寸不跃出目标区域)'
        },
        ///// 隐藏属性
        _camera: {
            get: function () {
                if (CC_EDITOR) return;
                //
                if (this.camera == null)
                    this.camera = this.camera || cc.find(this.cameraNodeName) || cc.Camera.main.node;
                return this.camera;
            },
            visible: false,
        },
        /**
         * 获取相机尺寸
         */
        _cameraSize: {
            get: function () {
                if (CC_EDITOR) return;
                //
                var camNode = this._camera;
                var sizeNode = this.cameraSize || camNode;
                // 将尺寸节点位置设置到相机位置
                Utils.node.syncTransform(camNode, sizeNode, true, false, false);
                // 获得尺寸节点的世界包围框
                var bounds = sizeNode.getBoundingBoxToWorld();
                // 频繁调用一下代码很耗时，还是设计时配置好sizeNode为妙
                if (bounds.width == 0 || bounds.height == 0) {
                    // 缓存中心
                    var center = bounds.center;
                    // var canvas = cc.game.canvas;
                    // (bounds.width == 0) && (bounds.width = canvas.width);
                    // (bounds.height == 0) && (bounds.height = canvas.height);
                    // 获得画布尺寸可见尺寸，即相机视野尺寸
                    var visibleSize = cc.view.getVisibleSize();
                    (bounds.width == 0) && (bounds.width = visibleSize.width);
                    (bounds.height == 0) && (bounds.height = visibleSize.height);
                    // 恢复中心
                    bounds.center = center;
                }
                return bounds;
            },
            visible: false,
        },
        /**
         * 获取相机边界
         */
        _cameraBounds: {
            get: function () {
                if (CC_EDITOR) return;
                //
                if (this.cameraBounds == null)
                    return null;
                return this.cameraBounds.getBoundingBoxToWorld();
            },
            visible: false,
        },
        /**
         * 获取目标尺寸
         */
        _targetSize: {
            get: function () {
                if (CC_EDITOR) return;
                //
                var sizeNode = this.targetSize || this.target;
                Utils.node.syncTransform(this.target, sizeNode, true, false, false);
                return sizeNode.getBoundingBoxToWorld();
            },
            visible: false,
        },
        /**
         * 获取目标边界
         */
        _targetBounds: {
            get: function () {
                if (CC_EDITOR) return;
                //
                if (this.targetBounds == null)
                    // return this._targetSize;
                    return this._cameraSize;
                return this.targetBounds.getBoundingBoxToWorld();
            },
            visible: false,
        },
    },

    update(dt) {
        //
        if (this.target == null)
            return;
        // 获取捕获目标的便宜
        var catchTargetOffset = this._f1(
            this._targetBounds, this._targetSize
        );
        catchTargetOffset.negSelf();
        var offset = catchTargetOffset.clone();
        // 获取相机范围限制
        var camBounds = this._cameraBounds;
        if (camBounds != null) {
            // 模拟相机偏移后的包围框
            var simCameraSize = this._cameraSize;
            simCameraSize.x += catchTargetOffset.x;
            simCameraSize.y += catchTargetOffset.y;
            // 获取模拟后的限制量
            var camBoundsOffset = this._f1(
                camBounds, simCameraSize
            );
            offset.addSelf(camBoundsOffset);
        }
        // 移动相机
        var camNode = this._camera;
        var camWP = Utils.node.getWorldPosition(camNode);
        camWP.addSelf(offset);
        Utils.node.setWorldPosition(camNode, camWP);
        // 处理相机视野缩放
        this.updateZoom();
    },
    updateZoom() {
        // 获得画布尺寸可见尺寸，即相机视野尺寸
        var visibleSize = cc.view.getVisibleSize();
        var ratio = Utils.misc.getScaleRatio(this._cameraSize, visibleSize);
        var camera = this._camera.getComponent(cc.Camera);
        //
        camera.zoomRatio = ratio;
    },

    /**
     * 计算为了将r限制在R内，需要的偏移量
     */
    _f1(R, r) {
        // x轴向偏移
        var xOffset = this._f0(R.xMin, R.xMax, r.xMin, r.xMax);
        var yOffset = this._f0(R.yMin, R.yMax, r.yMin, r.yMax);
        return new cc.Vec2(xOffset, yOffset);
    },
    /**
     * 计算为了将[e0, e1]限制在[E0, E1]内，需要的偏移量
     * 前提是[e0, e1]长度一定小于[E0, E1]
     */
    _f0(E0, E1, e0, e1) {
        var tmp;
        // 保证E0小于E1
        if (E0 > E1) {
            tmp = E1;
            E1 = E0;
            E0 = tmp;
        }
        // 保证e0小于e1
        if (e0 > e1) {
            tmp = e1;
            e1 = e0;
            e0 = tmp;
        }
        tmp = 0;
        if (e0 < E0) {
            tmp = E0 - e0;
        } else if (e1 > E1) {
            tmp = E1 - e1;
        }
        return tmp;
    },

});
